﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Collections.Specialized;
using System.ComponentModel;

namespace FutureTech.Collection
{
        /// <summary>
        /// 跨线程通知集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class AsyncObservableCollection<T>:ObservableCollection<T>
        {
                

                /// <summary>
                /// 初始化类的新实例
                /// </summary>
                public AsyncObservableCollection()
                {
                        
                }

                /// <summary>
                /// 初始化类的新实例，并从指定集合复制元素
                /// </summary>
                public AsyncObservableCollection(IEnumerable<T> list)
                        :base(list)
                {
                        
                }

                /// <summary>
                /// 线程上下文
                /// </summary>
                private readonly SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

                /// <summary>
                /// Raises the <see cref="E:CollectionChanged" /> event.
                /// </summary>
                /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
                protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
                {
                        if (SynchronizationContext.Current ==_synchronizationContext)
                        {
                                RaiseCollectionChanged(e);
                        }
                        else
                        {
                                _synchronizationContext.Post(RaiseCollectionChanged, e);
                        }
                }

                /// <summary>
                /// Raises the collection changed.
                /// </summary>
                /// <param name="param">The parameter.</param>
                private void RaiseCollectionChanged(object param)
                {
                        base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
                }

                /// <summary>
                /// Raises the <see cref="E:PropertyChanged" /> event.
                /// </summary>
                /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
                protected override void OnPropertyChanged(PropertyChangedEventArgs e)
                {
                        if (SynchronizationContext.Current != _synchronizationContext)
                        {
                                _synchronizationContext.Post(RaisePropertyChanged, e);

                        }
                }

                /// <summary>
                /// Raises the property changed.
                /// </summary>
                /// <param name="param">The parameter.</param>
                private void RaisePropertyChanged(object param)
                {
                        base.OnPropertyChanged((PropertyChangedEventArgs) param);
                }
        }
}
